using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using Portal.Api.FeedProvider;
using System.Globalization;

namespace Portal.Api
{
  /// <summary>
  /// Base class for each Portal Module Control. Provides the current Tab and Module Definition.
  /// </summary>
  public class Module : UserControl
  {
    /// <summary>
    /// The Module manager.
    /// </summary>
    private ModuleDocument _moduleDocument;

    /// <summary>
    /// The current Tab reference. Readonly
    /// </summary>
    public string TabRef { get { return _tabRef; } }
    private string _tabRef;

    private bool _hasEditRights;

    /// <summary>
    /// Initializes the Control. Called by the Portal Framework.
    /// </summary>
    /// <param name="tab"></param>
    /// <param name="module"></param>
    /// <param name="virtualPath"></param>
    public void InitModule(string tabRef, string moduleRef, string type, bool hasEditRights)
    {
      _moduleDocument = new ModuleDocument(moduleRef, type);
      _tabRef = tabRef;
      _hasEditRights = hasEditRights;
    }

    /// <summary>
    /// The Document for this module.
    /// </summary>
    public ModuleDocument Document { get { return _moduleDocument; } }

    /// <summary>
    /// Is the module visible? The Module can control its visibility by override this property.
    /// </summary>
    /// <returns>true if the Module should be visible</returns>
    public virtual bool IsVisible { get { return true; } }

    /// <summary>
    /// Build a URL to the current Page. Use this method to implement Modules that needs URL Parameter.
    /// </summary>
    /// <param name="parameter">URL Parameter.</param>
    /// <returns>URL with parameter</returns>
    /// <example>Response.Redirect(BuildURL("dir=myPhotos&size=large"));</example>
    public string BuildUrl(string parameter)
    {
      if (null == parameter)
        parameter = "";

      string p = "";
      if (!parameter.StartsWith("&", StringComparison.OrdinalIgnoreCase))
      {
        p = "&" + parameter;
      }
      else
      {
        p = parameter;
      }
      return Config.GetTabUrl(TabRef) + p;
    }

    public bool UserHasEditRights
    {
      get { return _hasEditRights; }
    }

    public static Module GetModuleControl(Control ctrl)
    {
      if (null == ctrl) return null;

      if (ctrl.GetType().IsSubclassOf(typeof(Module)))
        return (Module)ctrl;

      if (ctrl.Parent == null)
        return null;

      return GetModuleControl(ctrl.Parent);
    }

    /// <summary>
    /// Provides a link to an (rss) feed on this page.
    /// </summary>
    /// <param name="dataProvider">The class that provides the feed data.</param>
    /// <param name="title">The title of the feed</param>
    public void AddFeedLink(Type dataProvider, string title)
    {
      if(dataProvider == null)
        throw new ArgumentNullException("dataProvider");      

      HtmlLink link = new HtmlLink();
      link.Href = BuildFeedLink(dataProvider);
      link.Attributes.Add("rel", "alternate");
      link.Attributes.Add("type", "application/rss+xml");
      link.Attributes.Add("title", title);
      Page.Header.Controls.Add(link);
    }


    /// <summary>
    /// Builds a link to the designated dataProvider for the current module.
    /// </summary>
    /// <param name="dataProvider"></param>
    /// <returns></returns>
    public string BuildFeedLink(Type dataProvider)
    {
      if (dataProvider == null)
        throw new ArgumentNullException("dataProvider");

      if (null == dataProvider.GetInterface("IFeedDataProvider"))
        throw new ArgumentException("Argument does not implement interface IFeedDataProvider", "dataProvider");

      // Check if the attribute is implemented.
      FeedDataProviderAttribute dataProviderAttr = null;
      int foundAttr = 0;
      foreach (var attr in dataProvider.GetCustomAttributes(true))
      {
        if (attr.GetType() == typeof(FeedDataProviderAttribute))
        {
          foundAttr++;
          dataProviderAttr = attr as FeedDataProviderAttribute;

          // Check if this Attribute supports this Module Type.
          if (dataProviderAttr.ModuleType == Document.ModuleType)
            break;
          else
            dataProviderAttr = null;
        }
      }

      if (foundAttr == 0)
        throw new ArgumentException("Argument does not implement Attribute RssDataProvider", "dataProvider");

      if (dataProviderAttr == null)
        throw new ArgumentException("Argument does not implement Attribute RssDataProvider for this module type", "dataProvider");

      string url =  VirtualPathUtility.ToAbsolute("~/Feed.aspx");
      url += string.Format(CultureInfo.InvariantCulture, "?t={0}&m={1}", dataProviderAttr.Identifier, Document.ModuleRef);
      return url;
    }

    /// <summary>
    /// Returns the Url of the tab.
    /// </summary>
    /// <returns>The BackURL</returns>
    public string BackUrl
    {
      get
      {
        return Config.GetTabUrl(TabRef);
      }
    }

    /// <summary>
    /// Redirects back to the tab URL. Uses the GetBackURL() Method.
    /// </summary>
    public void RedirectBack()
    {
      Response.Redirect(BackUrl);
    }
  }



  /// <summary>
  /// Base class for each Portal Edit Module Control. Derived from Module.
  /// This class is obsolete. Use the attribute EditModule instead.
  /// </summary>
  public class EditModule : Module
  {

  }
}
